package com.dl698.axdr;

import com.dl698.asn1.axdr.AxdrType;
import com.dl698.util.ReverseByteArrayInputStream;
import com.dl698.util.ReverseByteArrayOutputStream;

/**
 * FactoryVersion类
 * 实现工厂版本信息的编解码
 * 
 * @author wind
 * @version 1.1.1
 */
public class FactoryVersion implements AxdrType {

    private byte[] dataCode = null;
    private VISIBLESTRING4 fcode = null;
    private VISIBLESTRING4 sver = null;
    private VISIBLESTRING6 sverDate = null;
    private VISIBLESTRING4 hver = null;
    private VISIBLESTRING6 hverDate = null;
    private VISIBLESTRING8 fextend = null;

    /**
     * 默认构造函数
     */
    public FactoryVersion() {
    }

    /**
     * 设置数据编码
     * 
     * @param dataCode 数据编码
     */
    public void setDataCode(byte[] dataCode) {
        this.dataCode = dataCode;
    }

    /**
     * 设置所有参数
     * 
     * @param fcode    工厂代码
     * @param sver     软件版本
     * @param sverDate 软件版本日期
     * @param hver     硬件版本
     * @param hverDate 硬件版本日期
     * @param fextend  扩展信息
     */
    public void setAll(VISIBLESTRING4 fcode, VISIBLESTRING4 sver, VISIBLESTRING6 sverDate,
            VISIBLESTRING4 hver, VISIBLESTRING6 hverDate, VISIBLESTRING8 fextend) {
        this.fcode = fcode;
        this.sver = sver;
        this.sverDate = sverDate;
        this.hver = hver;
        this.hverDate = hverDate;
        this.fextend = fextend;
    }

    @Override
    public int decode(ReverseByteArrayInputStream input) {
        int codeLength = 0;

        fcode = new VISIBLESTRING4();
        codeLength += fcode.decode(input);

        sver = new VISIBLESTRING4();
        codeLength += sver.decode(input);

        sverDate = new VISIBLESTRING6();
        codeLength += sverDate.decode(input);

        hver = new VISIBLESTRING4();
        codeLength += hver.decode(input);

        hverDate = new VISIBLESTRING6();
        codeLength += hverDate.decode(input);

        fextend = new VISIBLESTRING8();
        codeLength += fextend.decode(input);

        return codeLength;
    }

    @Override
    public int encode(ReverseByteArrayOutputStream output) {
        int codeLength;

        if (dataCode != null) {
            codeLength = dataCode.length;
            for (int i = dataCode.length - 1; i >= 0; i--) {
                try {
                    output.write(dataCode[i]);
                } catch (java.io.IOException e) {
                    throw new RuntimeException("IO exception during encode", e);
                }
            }
        } else {
            if (fcode != null && sver != null && sverDate != null && hver != null && hverDate != null
                    && fextend != null) {
                codeLength = 0;
                codeLength += fextend.encode(output);
                codeLength += hverDate.encode(output);
                codeLength += hver.encode(output);
                codeLength += sverDate.encode(output);
                codeLength += sver.encode(output);
                codeLength += fcode.encode(output);
            } else {
                throw new RuntimeException("fextend || hverDate || hver || sverDate || sver || fcode is null");
            }
        }
        return codeLength;
    }

    /**
     * 编码并保存
     * 
     * @param encodingSizeGuess 编码大小预估
     */
    public void encodeAndSave(int encodingSizeGuess) {
        ReverseByteArrayOutputStream revOStream = new ReverseByteArrayOutputStream();
        revOStream.setBufSize(encodingSizeGuess);
        encode(revOStream);
        this.dataCode = revOStream.getArray();
    }

    @Override
    public String toString() {
        if (fcode != null && sver != null && sverDate != null && hver != null && hverDate != null && fextend != null) {
            return "sequence: {" + "fcode: " + fcode + ", sver: " + sver + ", sverdate: " + sverDate + ", hver: " + hver
                    + ", hverdate: " + hverDate + ", fextend: " + fextend + "}";
        } else {
            return "fextend || hverDate || hver || sverDate || sver || fcode is null";
        }
    }
}